<template>
  <div class="tree-view">
    <div slot="right" :id="treeViewId" class="tree-view-container"></div>
    <!-- <MagicBox></MagicBox> -->
  </div>
</template>
<script>
/* eslint-disable global-require */
/* eslint-disable array-callback-return */
import G6 from '@antv/g6';

export default {
  // modify by wiz
  compName: 'oTreeView',

  name: 'tree-view',
  // components: {
  //   MagicBox
  // },
  props: {
    config: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
      treeViewId: 'treeViewId',
      graph: null,
      nodeId: '1',
      split1: 0.3,
      showMagicBoxField: '',
      showMagicBoxFieldToId: null,
      filterField: '',
      filterSQL: '1=1',
      // data: {
      //   nodes: [
      //     {
      //       id: "1",
      //       name: "根节点",
      //       conf: []
      //     }
      //   ]
      // }
      defaultGraphData: null
    };
  },
  created() {
    // 阻止浏览器默认右键菜单
    document.oncontextmenu = event => {
      if (event.stopPropagation) {
        event.stopPropagation();
      }
      if (event.preventDefault) {
        event.preventDefault();
      }
    };
  },
  mounted() {
    this.init();
    this.custNode();

    const width = document.getElementById(this.treeViewId).scrollWidth;
    const height = document.getElementById(this.treeViewId).scrollHeight || 500;

    const graph = new G6.Graph({
      container: this.treeViewId,
      width: width > 0 ? width - 500 : 800,
      height,
      layout: {
        type: 'dagre', // 层次布局
        rankdir: 'TB', // layout 的方向
        align: 'DL',
        nodesep: 50,
        ranksep: 50,
        controlPoints: false, // 是否保留布局连线的控制点
        workerEnabled: true // 是否启用 web-worker 以防布局计算时间过长阻塞页面交互
      },
      defaultNode: {
        type: 'wyOrganization'
      },
      defaultEdge: {
        type: 'polyline',
        style: {
          radius: 8,
          offset: 20,
          endArrow: false,
          lineWidth: 2.5,
          stroke: '#C2C8D5'
        }
      },

      modes: {
        default: [
          'drag-canvas',
          // "drag-node",
          'zoom-canvas',
          {
            type: 'brush-select',
            trigger: 'ctrl',
            includeEdges: false
          }
        ]
      },
      animate: true,
      fitView: true,
      fitViewPadding: [1, 100, 100, 100]
    });

    graph.on('node:mouseenter', evt => {
      const { item } = evt;
      graph.setItemState(item, 'hover', true);
    });

    graph.on('node:mouseleave', evt => {
      const { item } = evt;
      graph.setItemState(item, 'hover', false);
    });
    graph.on('node:click', evt => {
      const nodeELEName = evt.target.get('name');
      switch (nodeELEName) {
        case 'add-node':
          this.addNode(evt);
          break;
        case 'libFun':
          this.libFun(evt);
          break;
        case 'delNode':
          this.delNode(evt);
          break;
        default:
          break;
      }
    });
    if (this.defaultGraphData) {
      graph.read(this.defaultGraphData);
    }
    this.graph = graph;
  },
  methods: {
    init() {
      if (this.config) {
        if (this.config['showMagicBoxField']) {
          this.showMagicBoxField = this.config.showMagicBoxField;
        }
        if (this.config['showMagicBoxFieldToId']) {
          this.showMagicBoxFieldToId = this.config.showMagicBoxFieldToId;
        }
        if (this.config['defaultGraphData']) {
          this.defaultGraphData = this.config.defaultGraphData;
        }
        if (this.config['filterField']) {
          this.filterField = this.config.filterField;
        }
      }
    },
    custNode() {
      const me = this;
      G6.registerNode('wyOrganization', {
        getAnchorPoints() {
          return [
            [0.5, 0],
            [0.5, 1]
          ];
        },
        drawShape(cfg, group) {
          const shape = group.addShape('rect', {
            attrs: {
              x: -75,
              y: -25,
              width: 150,
              height: 50,
              radius: 10,
              stroke: '#5B8FF9',
              fill: '#C6E5FF',
              lineWidth: 3
            },
            name: 'rect-shape'
          });
          if (cfg.name) {
            group.addShape('text', {
              attrs: {
                text: cfg.name,
                x: 0,
                y: 0,
                fill: '#00287E',
                fontSize: 14,
                textAlign: 'center',
                textBaseline: 'middle',
                fontWeight: 'bold'
              },
              name: 'text-shape'
            });
          }
          group.addShape('image', {
            attrs: {
              x: -7,
              y: 10,
              width: 15,
              height: 15,
              img: require('@/assets/icons/jiahao.svg'),
              cursor: 'pointer'
              // opacity: 0
            },
            visible: false,
            name: 'add-node'
          });
          group.addShape('image', {
            attrs: {
              x: -7,
              y: -25,
              width: 15,
              height: 15,
              img: require('@/assets/icons/open.svg'),
              cursor: 'pointer'
              // opacity: 0
            },
            visible: false,
            name: 'libFun'
          });
          group.addShape('image', {
            attrs: {
              x: 55,
              y: 10,
              width: 15,
              height: 15,
              img: require('@/assets/icons/shanchu.svg'),
              cursor: 'pointer'
              // opacity: 0
            },
            visible: false,
            name: 'delNode'
          });
          return shape;
        },
        setState(name, value, item) {
          me.graph.setAutoPaint(false);
          const group = item.getContainer();
          const childrens = group.get('children');
          if (name === 'hover') {
            if (value) {
              childrens.forEach((v, index) => {
                if (index === 0) {
                  v.attr('stroke', '#d9d9d9');
                }
                if (index === 2 || index === 3 || index === 4) {
                  v.cfg.visible = true;
                }
              });
            } else {
              childrens.forEach((v, index) => {
                if (index === 0) {
                  v.attr('stroke', '#5B8FF9');
                }

                if (index === 2 || index === 3 || index === 4) {
                  v.cfg.visible = false;
                }
              });
            }
          }
          me.graph.setAutoPaint(true);
        }
      });
    },
    addNode(e) {
      const { item } = e;
      const m = item.getModel();
      const nodeELEName = e.target.get('name');
      if (nodeELEName === 'add-node') {
        const vId = `${+this.nodeId + 1}`;
        this.nodeId = vId;
        this.graph.addItem('node', {
          id: vId,
          x: m.x,
          y: m.y,
          name: vId,
          conf: []
        });

        this.graph.addItem('edge', {
          source: item.get('id'),
          target: vId
        });

        this.graph.layout();
        // this.arefreshDragedNodePosition(e);
      }
    },
    libFun(e) {
      const me = this;
      let parentNode = [];
      const { item } = e;
      const currNodeId = item.getModel()['id'];

      parentNode = this.graph.getEdges().filter(v => {
        return v.getTarget().getModel().id === currNodeId;
      });
      if (parentNode.length > 0) {
        const m = parentNode[0].get('sourceNode').getModel();
        let parentNodeId = 0;
        if (m.conf.length > 0) {
          parentNodeId = m.conf[0].id;
        }
        if (parentNodeId > 0) {
          this.filterSQL = `${this.filterField}=${parentNodeId}`;
        } else {
          this.filterSQL = '1=1';
        }
      } else {
        this.filterSQL = '1=1';
      }

      Tsrv.utils
        .createModal('oMagicBox', {
          source: {
            funid: null,
            field: this.showMagicBoxField,
            limit: 1,
            filter: {
              // globalSearch: this.filterSQL //filter动态条件
              initSearch: this.filterSQL // filter静态条件
            }
          },
          config
        })
        .then(res => {
          if (res) {
            this.$emit('out_update_item', { item, res });
          }
        });

      // me.$bus.$emit(

      //   {
      //     funid: null,
      //     field: this.showMagicBoxField,
      //     limit: 1,
      //     filter: {
      //       // globalSearch: this.filterSQL //filter动态条件
      //       initSearch: this.filterSQL //filter静态条件
      //     }
      //   },

      //   this.showMagicBoxFieldToId
      // );
      // me.$bus.$on(this.showMagicBoxFieldToId, res => {
      //   me.$bus.$off(this.showMagicBoxFieldToId);
      //   this.$emit("out_update_item", { item: item, res: res });
      // });
    },
    delNode(e) {
      const me = this;
      let delNodes = [];
      const { item } = e;
      const nodeId = item.get('id');

      delNodes = this.getDelNodes(me.graph.getEdges(), nodeId);
      me.graph.removeItem(nodeId);
      delNodes.map(v => {
        me.graph.removeItem(v);
      });
      me.graph.layout();
    },
    getDelNodes(edges, nodeId) {
      let childNode = [];
      const delNode = [];
      childNode = edges.filter(v => {
        return v.getSource().getModel()['id'] === nodeId;
      });
      childNode.map(v => {
        delNode.push(v.getTarget().getModel()['id']);
      });
      childNode.map(v => {
        let grandsonNode = [];
        const targetNodeId = v.getTarget().getModel()['id'];
        if (targetNodeId) {
          grandsonNode = this.getDelNodes(edges, targetNodeId);
          grandsonNode.forEach(vc => {
            delNode.push(vc);
          });
        }
      });
      return delNode;
    },
    refreshDragedNodePosition(e) {
      const model = e.item.get('model');
      model.fx = e.x;
      model.fy = e.y;
    },
    saveData() {
      const data = this.graph.save();
      // 保存this.data.nodeId
      data.maxNodeId = this.nodeId;
      // 保存数据json
      // JSON.stringify(data)
    },
    openData(data) {
      // 请求数据得到 g6数据

      this.graph.read(data);
      // 到图最大ID号 保存到 this.data.nodeId
      // this.nodeId = data.maxNodeID
    }
  }
};
</script>
<style lang="scss" scoped>
.tree-view,
.tree-view-container {
  height: 100%;
  width: 100%;
}
</style>
